home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / UUPC11QS.ARJ / MLIB.C < prev    next >
C/C++ Source or Header  |  1991-10-20  |  12KB  |  397 lines

  1. /*
  2.    ibmpc/mlib.c   by <skl@van-bc.UUCP>   August/87
  3.  
  4.  
  5.    Mailer UA system-dependent library
  6.  
  7.    Services to provide in mlib.c:
  8.  
  9.    Get a single character from the console.
  10.    Invoke the local editor on a given file.
  11.    Determine if a given file stream points to the console.
  12.    Get a line from the console.
  13.    Invoke a local pager on a given file.
  14.  
  15.    Update history:
  16.  
  17.    13 May 89      Use PC format path names for editor                   ahd
  18.    01 Oct 89      Make Console_fgets use far pointers
  19.                   Alter Console_fgets and Is_Console to type boolean
  20.                                                                         ahd
  21.    29 Jul 90      Use PC format path names for pager                    ahd
  22. */
  23.  
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <conio.h>
  28. #include <io.h>
  29. #include <dos.h>
  30.  
  31. #include "lib.h"
  32. #include "hlib.h"
  33.  
  34. #ifdef FAMILYAPI
  35. #define SIMPLE_CONSOLE_FGETS
  36. #endif
  37.  
  38. #ifndef SIMPLE_CONSOLE_FGETS
  39. #define MULTIPLEX 0x2f        /* 8086 DOS Interrupt for multiplexing */
  40.  
  41. static int DOSRead( char *buff, const int buflen);
  42.  
  43. static boolean DOSKeyActive( void );
  44.  
  45. static int DOSKeyRead( char *buff , int buflen );
  46.  
  47. #endif
  48.  
  49.  
  50. /*
  51.    G e t _ O n e
  52.  
  53.    Get a single character from the console
  54. */
  55.  
  56. int Get_One()
  57. {
  58.  
  59.    return getch();
  60.  
  61. } /*Get_One*/
  62.  
  63.  
  64. /*
  65.    I n v o k e _ E d i t o r
  66.  
  67.    Invoke the user's editor to edit a text file
  68. */
  69.  
  70. int Invoke_Editor(const char *ecmd, const char *filename)
  71. {
  72.    char command[FILENAME_MAX*2 + 1];
  73.    char tempname[FILENAME_MAX];                          /* ahd   */
  74.    int  column = 0;                                      /* ahd   */
  75.  
  76.    if (ecmd == nil(char)) {
  77.       printf("Invoke_Editor: No editor specified.\n");
  78.       return 1;
  79.    }
  80.  
  81.    puts("\nInvoking editor ...\n");
  82.  
  83.    strcpy(tempname,filename);                            /* ahd   */
  84.  
  85.    while (tempname[column] != '\0') {                    /* ahd   */
  86.       if (tempname[column] ==  '/')                      /* ahd   */
  87.          tempname[column] = '\\';                        /* ahd   */
  88.       column = column + 1;                               /* ahd   */
  89.   }                                                      /* ahd   */
  90.  
  91.  
  92.    sprintf(command, ecmd, tempname);                     /* ahd   */
  93.    if (system(command) != 0) {
  94.       printf("Invoke_Editor: system(\"%s\") failed.\n", command);
  95.       return 2;
  96.    }
  97.  
  98.    return 0;
  99.  
  100. } /*Invoke_Editor*/
  101.  
  102.  
  103. /*
  104.    Is_Console - is this stream from the console?
  105.  
  106.    Note: isatty actually returns if the stream is a character device,
  107.          thus causing device NUL to appear interactive; this is not
  108.          acceptable, but I don't know a trivial fix.           ahd
  109. */
  110.  
  111. boolean Is_Console(FILE *stream)                                  /* ahd   */
  112. {
  113.  
  114.    return isatty(fileno(stream));
  115.  
  116. } /*Is_Console*/
  117.  
  118.  
  119. /*
  120.    Console_fgets - get a line of input from the local console
  121.  
  122.    This is a hook to allow for using the local system's facility
  123.    for input line editing.  We call DOS to perform a line read,
  124.    thus allowing utilities like DOSEDIT or CED to do their fancy work.
  125. */
  126.  
  127. #ifndef SIMPLE_CONSOLE_FGETS
  128.  
  129. boolean Console_fgets(char *buff, int buflen, char *prompt)
  130. {
  131.    static boolean eof = FALSE;    /* pending EOF flag  */
  132.  
  133.    char *eofptr;
  134.  
  135.    if (eof) {           /* have a pending EOF?  */
  136.       eof = FALSE;      /* no more pending EOF  */
  137.       return FALSE;     /* signal the EOF    */
  138.    }
  139.  
  140. /*--------------------------------------------------------------------*/
  141. /*      Prompt the user, read the data, and then go to a new line     */
  142. /*--------------------------------------------------------------------*/
  143.  
  144.    fputs(prompt, stdout);
  145.  
  146.    if ( DOSKeyActive() )
  147.       buflen = DOSKeyRead( buff, buflen );
  148.    else
  149.       buflen = DOSRead( buff, buflen );
  150.     putchar('\n');
  151.  
  152. /*--------------------------------------------------------------------*/
  153. /*             Determine if we hit end of file on the read            */
  154. /*--------------------------------------------------------------------*/
  155.  
  156.    if ( buflen == -1 )
  157.    {
  158.       *buff = '\0';
  159.       return FALSE;
  160.    }
  161.  
  162. /*--------------------------------------------------------------------*/
  163. /*                        Terminate the buffer                        */
  164. /*--------------------------------------------------------------------*/
  165.  
  166.    buff[buflen] = '\n';
  167.    buff[buflen + 1] = '\0';
  168.  
  169.    if ((eofptr = strchr(buff, '\x1a')) == nil(char))
  170.       return TRUE;      /* an ordinary successful read   */
  171.    else if (eofptr == buff)
  172.    {
  173.       return FALSE;     /* signal EOF right away      */
  174.    }
  175.    else {
  176.       eof = TRUE;       /* we now have a pending EOF  */
  177.       *eofptr = '\0';
  178.       return TRUE;      /* read successful but EOF next  */
  179.    } /* else */
  180.  
  181. } /*Console_fgets*/
  182.  
  183. /*--------------------------------------------------------------------*/
  184. /*    D O S R e a d                                                   */
  185. /*                                                                    */
  186. /*    Read from console under DOS without DOSKEY                      */
  187. /*--------------------------------------------------------------------*/
  188.  
  189. static int DOSRead( char *buff, const int buflen)
  190. {
  191.    union REGS regs;
  192.    struct SREGS sregs;
  193.  
  194.    struct {
  195.       unsigned char maximum, actual;
  196.       char buffer[255];
  197.    } request;
  198.  
  199.    char far *p = (char far *) &request;
  200.  
  201. /*--------------------------------------------------------------------*/
  202. /*            Set up the address of our read buffer for DOS           */
  203. /*--------------------------------------------------------------------*/
  204.  
  205.    sregs.ds = FP_SEG( p );    /* Use segment of the buffer           */
  206.    regs.x.dx = (unsigned int)(&request);
  207.    request.maximum = (unsigned char) min( buflen - 1,
  208.                                           sizeof request.buffer);
  209.    regs.h.ah = 0x0a;          /* Buffered keyboard input             */
  210.  
  211. /*--------------------------------------------------------------------*/
  212. /*                  Invoke the buffered console read                  */
  213. /*--------------------------------------------------------------------*/
  214.  
  215.    intdosx(®s, ®s, &sregs);
  216.  
  217. /*--------------------------------------------------------------------*/
  218. /*                        Now return the result                       */
  219. /*--------------------------------------------------------------------*/
  220.  
  221.    memcpy( buff, request.buffer, request.actual );
  222.    return (unsigned int) request.actual;
  223.  
  224. } /* DOSRead */
  225.  
  226. /*--------------------------------------------------------------------*/
  227. /*    D O S K e y A c t i v e                                         */
  228. /*                                                                    */
  229. /*    Determine if the DOS Key command line editor is active          */
  230. /*--------------------------------------------------------------------*/
  231.  
  232. static boolean DOSKeyActive( void )
  233. {
  234.    static boolean first_pass = TRUE;
  235.    static boolean active = FALSE;
  236.  
  237.    if ( first_pass )
  238.    {
  239.       first_pass = FALSE;
  240.       if ((_osmajor > 4) )
  241.       {
  242.          union REGS regs;
  243.  
  244. #ifdef __TURBOC__
  245.          if ( getvect( MULTIPLEX ) == NULL )
  246. #else
  247.          if ( _dos_getvect( MULTIPLEX ) == NULL )
  248. #endif
  249.             printmsg(0,"Multiplex interrupt not installed???\n");
  250.          else {
  251.             regs.x.ax = 0x4800;     /* Request for DOS Key active */
  252.             int86( MULTIPLEX , ®s, ®s );
  253.             if ( regs.h.al != 0x00 )
  254.                active = TRUE;
  255.          }
  256.       } /* if (_osmajor > 4 ) */
  257.    } /* if ( first_pass ) */
  258.  
  259. /*--------------------------------------------------------------------*/
  260. /*                          Return to caller                          */
  261. /*--------------------------------------------------------------------*/
  262.  
  263.    if ( bflag[F_DOSKEY] && ! active )
  264.    {
  265.      printmsg(0,"DOSKEY support not enabled, option disabled");
  266.      bflag[F_DOSKEY] = FALSE;
  267.    }
  268.  
  269.    return bflag[F_DOSKEY] && active;
  270.  
  271. } /* DOSKeyActive */
  272.  
  273.  
  274. /*--------------------------------------------------------------------*/
  275. /*    D O S K e y R e a d                                             */
  276. /*                                                                    */
  277. /*    Read a line from the terminal using DOS Key                     */
  278. /*--------------------------------------------------------------------*/
  279.  
  280. static int DOSKeyRead( char *buff , int buflen )
  281. {
  282.    union REGS regs;
  283.    struct SREGS sregs;
  284.  
  285.    struct {
  286.       unsigned char maximum, actual;
  287.       char buffer[126];
  288.    } request;
  289.  
  290.    char far *p = (char far *) &request;
  291.  
  292. /*--------------------------------------------------------------------*/
  293. /*                   Set up for the DOSKEY read call                  */
  294. /*--------------------------------------------------------------------*/
  295.  
  296.    sregs.ds = FP_SEG( p );    /* Use segment of the buffer           */
  297.    regs.x.dx = (unsigned int)(&request);
  298.    regs.x.ax = 0x4810;
  299.    request.maximum = (unsigned char) min( buflen - 1, sizeof request );
  300.  
  301. /*--------------------------------------------------------------------*/
  302. /*                      Issue the call to DOSKEY                      */
  303. /*--------------------------------------------------------------------*/
  304.  
  305.    int86x( MULTIPLEX, ®s, ®s, &sregs );
  306.  
  307. /*--------------------------------------------------------------------*/
  308. /*                          Check the result                          */
  309. /*--------------------------------------------------------------------*/
  310.  
  311.    if ( regs.x.ax == 0 )      /* Function succeed?                */
  312.    {
  313.       buflen = request.actual;
  314.       memcpy( buff, request.buffer , buflen );
  315.    } /* if ( regs.x.ax == 0 ) */
  316.    else {                        /* Function failed, report it    */
  317.       printmsg(0,"DOSKEY read failed!");
  318.       buflen = -1;
  319.    } /* else */
  320.  
  321. /*--------------------------------------------------------------------*/
  322. /*                          Return to caller                          */
  323. /*--------------------------------------------------------------------*/
  324.  
  325.    return buflen;
  326.  
  327. } /* DOSKeyRead */
  328.  
  329. #else
  330.  
  331. boolean Console_fgets(char *buff, int buflen, char *prompt)
  332. {
  333.  
  334.    if (bflag[F_DOSKEY] )
  335.    {
  336.      printmsg(0,"DOSKEY support not available, option disabled");
  337.      bflag[F_DOSKEY] = FALSE;
  338.    }
  339.  
  340.    fputs(prompt, stdout);
  341.  
  342.    return (fgets(buff, buflen, stdin) != nil(char)) ? TRUE : FALSE;
  343.  
  344. } /*Console_fgets*/
  345.  
  346. #endif
  347.  
  348.  
  349. /*
  350.    L _ i n v o k e _ p a g e r
  351.  
  352.    Invoke the user's pager to view a text file
  353. */
  354.  
  355. int L_invoke_pager(const char *pcmd, const char *filename)
  356. {
  357.    char command[FILENAME_MAX*2 + 1];
  358.    char tempname[FILENAME_MAX];                          /* ahd   */
  359.    int  column = 0;                                      /* ahd   */
  360.  
  361.    if (pcmd == nil(char)) {
  362.       printf("L_invoke_pager: No pager specified.\n");
  363.       return 1;
  364.    }
  365.  
  366.    strcpy(tempname,filename);                            /* ahd   */
  367.  
  368.    while (tempname[column] != '\0') {                    /* ahd   */
  369.       if (tempname[column] ==  '/')                      /* ahd   */
  370.          tempname[column] = '\\';                        /* ahd   */
  371.       column += 1;                                       /* ahd   */
  372.   }                                                      /* ahd   */
  373.  
  374.    sprintf(command, pcmd, tempname);
  375.    if (system(command) != 0) {
  376.       printf("L_invoke_pager: system(\"%s\") failed.\n", command);
  377.       return 2;
  378.    }
  379.  
  380.    return 0;
  381.  
  382. } /*L_invoke_pager*/
  383.  
  384. /*
  385.       C l e a r
  386.  
  387.       Clear the screen
  388.  */
  389. void ClearScreen()
  390. {
  391. #ifdef __TURBOC__                                           /* pdm */
  392.       clrscr();                                             /* ahd */
  393. #else                                                       /* pdm */
  394.       fputs("\033[2J", stdout);     /* ANSI Erase screen       ahd */
  395. #endif                                                      /* pdm */
  396. }
  397.